home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1990 Aladdin Enterprises. All rights reserved.
- Distributed by Free Software Foundation, Inc.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /* z2bseq.c */
- /* Level 2 binary object sequence operators */
- #include "ghost.h"
- #include "errors.h"
- #include "oper.h"
- #include "stream.h"
- #include "name.h"
- #include "i2btoken.h"
- #include "i2bseq.h"
-
- typedef struct { ulong refs, chars; } bin_space;
-
- /* Compute the size of a binary object sequence */
- private int
- bin_seq_space(ref *op, int array_ok, bin_space *sp)
- { switch ( r_type(op) )
- {
- case t_null: case t_integer: case t_real:
- case t_boolean: case t_mark:
- sp->refs++; break;
- case t_string:
- sp->refs++; sp->chars += op->size; break;
- case t_name:
- sp->refs++;
- { ref nstr;
- name_string_ref(op, &nstr);
- sp->chars += nstr.size;
- }
- break;
- case t_array:
- if ( !array_ok ) return e_limitcheck;
- sp->refs += op->size;
- { uint i;
- for ( i = 0; i < op->size; i++ )
- { int code = bin_seq_space(op->value.refs + i, 0, sp);
- if ( code < 0 ) return code;
- }
- }
- break;
- default:
- return e_typecheck;
- }
- return 0;
- }
-
- /* Write the objects part of a binary object sequence. */
- /* Return the new offset in the string part. */
- private uint
- bin_seq_write(stream *s, ref *op, byte tag, uint spos)
- { bin_seq_obj ob;
- ref nstr;
- ob.unused = tag;
- switch ( r_type(op) )
- {
- case t_null: ob.tx = bs_null; break;
- case t_mark: ob.tx = bs_mark; break;
- case t_integer: ob.tx = bs_integer; ob.value.w = op->value.intval;
- swb: /* swap bytes of value if needed */
- /***** NYI *****/
- break;
- case t_real: ob.tx = bs_real; ob.value.f = op->value.intval;
- /***** handle non-IEEE native *****/
- goto swb;
- case t_boolean: ob.tx = bs_boolean; ob.value.w = op->value.index;
- goto swb;
- case t_array:
- { uint i;
- for ( i = 0; i < op->size; i++ )
- spos = bin_seq_write(s, op->value.refs + i, 0, spos);
- }
- break;
- case t_string: ob.tx = bs_string;
- if ( r_has_attrs(op, a_executable) ) ob.tx += bs_executable;
- nos: ob.size.w = op->size;
- /* *** swap bytes if needed *** */
- ob.value.w = spos;
- spos += op->size;
- goto swb;
- case t_name: ob.tx = bs_name;
- name_string_ref(op, &nstr);
- op = &nstr;
- goto nos;
- }
- swrite(s, (byte *)&ob, sizeof(bin_seq_obj));
- return spos;
- }
-
- /* Write the string part of a binary object sequence */
- private void
- bin_seq_write_strings(stream *s, ref *op)
- { switch ( r_type(op) )
- {
- case t_string:
- swrite(s, op->value.bytes, op->size);
- break;
- case t_name:
- { ref nstr;
- name_string_ref(op, &nstr);
- swrite(s, nstr.value.bytes, nstr.size);
- }
- break;
- }
- }
-
- /* Public interface for writing an object (printobject/writeobject) */
- int
- write_bin_object(register stream *s, byte tag, ref *op, int bin_format)
- { bin_space space;
- int code;
- ulong total;
- space.refs = space.chars = 0;
- code = bin_seq_space(op, 1, &space);
- if ( code < 0 ) return code;
- /* Object has been validated, only possible error now is */
- /* ioerror (which we don't check for). */
- total = 4 + sizeof(bin_seq_obj) + space.refs * sizeof(bin_seq_obj) + space.chars;
- if ( total > 0xffff ) return e_limitcheck;
- sputc(s, bt_seq + bin_format);
- sputc(s, 1);
- sputshort(s, (ushort)total);
- if ( r_type(op) == t_array )
- { sputc(s, bs_array +
- (r_has_attrs(op, a_executable) ? bs_executable : 0));
- sputc(s, tag);
- sputshort(s, op->size);
- sputlong(s, 4 + sizeof(bin_seq_obj));
- tag = 0;
- }
- bin_seq_write(s, op, tag, (uint)(total - space.chars));
- bin_seq_write_strings(s, op);
- return 0;
- }
-